use std::cell::RefCell;
use std::ops::{Add, Deref};
use std::rc::Rc;
use chrono::{Local, TimeDelta};
use yew::{function_component, html, use_context, use_state, Callback, Component, Context, Html};
use crate::db::service::im_collect_service::ImCollectService;
use crate::db::service::im_config_service::{clean_configs, count_total_config, create_index_for_configs, drop_index_for_configs, query_configs};
use crate::db::service::im_demo_service::{drop_tables};
use crate::db::service::im_department_service::{query_departments, total_department};
use crate::db::service::im_feedback_service::ImFeedbackService;
use crate::db::service::im_group_service::ImGroupService;
use crate::db::service::im_label_service::ImLabelService;
use crate::db::service::im_message_service::ImMessageService;
use crate::db::service::im_module_service::ImModuleService;
use crate::db::service::im_sensitive_word_service::ImSensitiveWordService;
use crate::db::service::im_session_service::ImSessionService;
use crate::db::service::im_user_service::ImUserService;
use crate::business::app_state::AppState;
use crate::business::websocket::receive_send_handle::ImReceiveSendHandleMsg;
use crate::business::websocket::send_data_router::{RpcRequest, RpcResponse};
use crate::business::websocket::dto::ping_dto::PingReq;
use crate::business::websocket::dto::user_dto::LoginResp;
use crate::db::dao::im_message_dao::query_hot_message_total;
use crate::db::db::Db;

#[derive(Clone, PartialEq)]
pub struct DemoState {
    counter: u32,
}

#[function_component(Demo)]
pub fn list() -> Html {
    let app_state = use_context::<AppState>().unwrap();
    let current_user_id = "test00100".to_string();
    let total = app_state.total;

    log::info!("Total: {}", total);

    // spawn_local(async move {
    //     let list = query();
    //     log::info!("html!!!!!!!!!!!!!!!!!!!!!!!!!!!!222, {}", list.iter().map(|e: &Employee| format!("{}-{}-{}", &e.id, &e.name, &e.salary)).collect::<Vec<String>>().join(","));
    // });

    let counter = use_state(|| DemoState {counter: 0});

    // 回调修改状态：通过 `set_counter` 更新值
    let onclick = Callback::from({
        let counter = counter.clone();
        move |_| {
            let new_value = counter.counter + 1;
            counter.set(DemoState {counter: new_value});
        }
    });

    let json_click = Callback::from(move |_| {
        let json_str = "{\"userId\":\"test00100\",\"tenantCode\":\"0000\",\"serverDateTime\":\"2025-06-24 14:45:49.829\",\"authToken\":\"ED0C702A603660E2EE89E99E69B0605DE3DC2D2C\",\"token\":\"38B1191AAE39405DC581D6292D76B35C6891B20E\",\"authCode\":144558409,\"coder\":0,\"successDataTime\":\"2025-06-24 14:45:49.829\",\"localSeq\":\"Tue, 24 Jun 2025 06:45:49 +0000_00001\"}";
        let login_resp: LoginResp = serde_json::from_str(json_str).unwrap();
        log::info!("LoginResp: {:?}", login_resp);
    });

    let state2 = app_state.clone();
    let ping_click = Callback::from(move |_| {
        let ping_req = PingReq {};

        log::info!("begin ping 1111111111111",);
        let callback = Callback::from(ping_success);
        let receive_send_handle = state2.receive_send_handle.clone();
        if let Some(receive_send_handle) = receive_send_handle {
            receive_send_handle.dispatch(ImReceiveSendHandleMsg::Request(RpcRequest::Ping(ping_req), callback));
        }
    });

    let app_state_clone = app_state.clone();
    let _user_id = current_user_id.clone();

    let show_config_callback = Callback::from(move |_| {
        log::info!("show config start");
        let total = count_total_config();
        log::info!("config total: {}", total);
        let configs = query_configs();
        for config in configs {
            log::info!("config: {:?}", config);
        }
        log::info!("show config end");
    });

    let delete_config_callback = Callback::from(move |_| {
        log::info!("clean config start");
        clean_configs();
        let total = count_total_config();
        log::info!("config total: {}", total);
        let configs = query_configs();
        for config in configs {
            log::info!("config: {:?}", config);
        }
        log::info!("clean config end");
    });

    let create_index_config_callback = Callback::from(move |_| {
        log::info!("create index for config start");
        create_index_for_configs();
        let total = count_total_config();
        log::info!("config total: {}", total);
        let configs = query_configs();
        for config in configs {
            log::info!("config: {:?}", config);
        }
        log::info!("create index for config end");
    });

    let drop_index_config_callback = Callback::from(move |_| {
        log::info!("drop index for config start");
        drop_index_for_configs();
        let total = count_total_config();
        log::info!("config total: {}", total);
        log::info!("drop index for config end");
    });

    let drop_table_callback = Callback::from(move |_| {
        log::info!("drop table start");
        drop_tables();
        log::info!("drop table end");
    });

    let show_department_callback = Callback::from(move |_| {
        log::info!("show department start");
        let total = total_department();
        log::info!("department total: {}", total);
        let departments = query_departments();
        for department in departments {
            log::info!("department: {:?}", department);
        }
        log::info!("show department end");
    });

    let show_user_callback = Callback::from(move |_| {
        log::info!("show user start");
        let user_service = ImUserService;
        let total = user_service.total();
        log::info!("show user end, total: {}", total);
    });

    let show_group_callback = Callback::from(move |_| {
        log::info!("show group start");
        let group_service = ImGroupService;
        let total = group_service.total();
        log::info!("show group end, total: {}", total);
    });

    let show_module_callback = Callback::from(move |_| {
        log::info!("show module start");
        let module_service = ImModuleService;
        let total = module_service.total();
        log::info!("show module end, total: {}", total);
    });

    let show_session_callback = Callback::from(move |_| {
        log::info!("show session start");
        let session_service = ImSessionService;
        let total = session_service.total();
        log::info!("show session end, total: {}", total);

        let ss = session_service.query("test00100", 0, 200);
        log::info!("show sessions, info: {:?}", ss);
    });

    let show_message_callback = Callback::from(move |_| {
        log::info!("show message start");
        let message_service = ImMessageService;
        let total = message_service.total();
        log::info!("show message end, total: {}", total);
    });

    let show_label_callback = Callback::from(move |_| {
        log::info!("show label start");
        let label_service = ImLabelService;
        let total = label_service.total();
        log::info!("show label end, total: {}", total);
    });

    let show_collect_callback = Callback::from(move |_| {
        log::info!("show collect start");
        let collect_service = ImCollectService;
        let total = collect_service.total();
        log::info!("show collect end, total: {}", total);
    });

    let show_feedback_callback = Callback::from(move |_| {
        log::info!("show feedback start");
        let feedback_service = ImFeedbackService;
        let total = feedback_service.total();
        log::info!("show feedback end, total: {}", total);
    });

    let show_sensitive_word_callback = Callback::from(move |_| {
        log::info!("show sensitive word start");
        let sensitive_word_service = ImSensitiveWordService;
        let total = sensitive_word_service.total();
        log::info!("show sensitive word end, total: {}", total);
    });

    let show_message2_callback = Callback::from(move |_| {
        log::info!("show message start");
        let message_service = ImMessageService;
        let total = message_service.total();
        let total2 = message_service.message_send_total();

        let message = message_service.query_messages(500);
        log::info!("show message end, {:?}", message);
    });
    let check_hot_message = Callback::from(move |_| {
        let db = Db::open();
        let user_id = "test00100";
        let start_date = Local::now();
        let start_date = start_date.add(TimeDelta::days(-14));
        let hot_messages = query_hot_message_total(db.clone(), user_id, start_date);
        log::info!("check hot messages, data: {:?}", hot_messages);
    });

    html! {
        <div>
            <h1 class="text-4xl font-bold text-center mb-8">{ "Scroll-RS Demo" }</h1>
        
            <div id="top" class="h-96 bg-gray-700 p-8 text-center">
                <h2 class="text-3xl font-bold">{ "Top of the Page" }</h2>
                <p>{ "Scroll down to see buttons in action!" }</p>
            </div>

            <div id="bottom" class="h-96 bg-gray-800 p-8 text-center">
                <h2 class="text-3xl font-bold">{ "Bottom of the Page" }</h2>
                <p>{ "You reached the bottom!" }</p>
            </div>

           // <button onclick={pull_config_callback}> { "pull config" }</button>
           <button onclick={show_config_callback}> { "show config" }</button>
           <button onclick={delete_config_callback}> { "clean config" }</button>
           <button onclick={create_index_config_callback}> { "create index config" }</button>
           <button onclick={drop_index_config_callback}> { "drop index config" }</button>
           <button onclick={drop_table_callback}> { "清理数据库" }</button>

          <hr/>

          <button onclick={show_department_callback}> { "show departments" }</button>
          <button onclick={show_user_callback}> { "total user" }</button>
          <button onclick={show_group_callback}> { "total groups" }</button>
          <button onclick={show_module_callback}> { "total modules" }</button>
          <button onclick={show_session_callback}> { "total session" }</button>
          <button onclick={show_message_callback}> { "total message" }</button>
        
          <h1> {"total: "} {total }</h1>
        
          <button onclick={show_label_callback}> { "total label" }</button>
          <button onclick={show_collect_callback}> { "total collect" }</button>
          <button onclick={show_feedback_callback}> { "total feedback" }</button>
          <button onclick={show_sensitive_word_callback}> { "total sensitive word" }</button>
          <button onclick={show_message2_callback}> { "total message" }</button>
          <button onclick={check_hot_message}> { "check hot message" }</button>

           <h1> {"total: "} {total }</h1>

            <div>
                <button {onclick}>{ "Increment" }</button>
                <button onclick={json_click}>{ "json" }</button>
                <button onclick={ping_click}>{ "ping" }</button>
                <p>{ counter.counter }</p>
            </div>
        </div>
    }
}

pub struct Demo2 {
    counter: Rc<RefCell<u32>>,
}

impl Component for Demo2 {
    type Message = ();
    type Properties = ();

    fn create(_ctx: &Context<Self>) -> Self {
        Self {
            counter: Rc::new(RefCell::new(0)),
        }
    }

    fn view(&self, _ctx: &Context<Self>) -> Html {
        // 克隆 Rc 以传递到回调中
        let counter_ref = self.counter.clone();

        // 创建修改状态的回调
        let onclick = Callback::from(move |_| {
            let counter = counter_ref.borrow_mut(); // 获取可变借用
            let nv = counter.add(1);
            
            log::info!("Counter: {}", nv);
        });

        html! {
            <button {onclick}>{ "Increment:" } { self.counter.borrow().deref() }</button>
        }
    }
}

pub fn ping_success(rpc_response: RpcResponse) {
    log::info!("ping success: {:?}", rpc_response);
}